﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="GrundlagenDesGradsystemsSteps.cs" company="https://code.google.com/p/clean-code-register/">
//   MIT
// </copyright>
// <summary>
//   Schritte des Features Grundlagen des Gradsystems.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace CleanCodeRegister.Specification.Steps
{
    using System;
    using System.Linq;

    using CleanCodeRegister.Model;

    using NUnit.Framework;

    using TechTalk.SpecFlow;

    /// <summary>
    /// Schritte des Features Grundlagen des Gradsystems.
    /// </summary>
    [Binding]
    public class GrundlagenDesGradsystemsSteps
    {
        private CleanCodeDeveloper me;

        private Reflektion reflektion;

        private Register register;

        private DateTime Stichtag { get; set; }

        /// <summary>
        /// The given ich interessiere mich fur clean code development.
        /// </summary>
        [Given(@"Ich interessiere mich für Clean Code Development")]
        public void GivenIchInteressiereMichFurCleanCodeDevelopment()
        {
            this.me = new CleanCodeDeveloper();
        }

        /// <summary>
        /// The given ich trage das armband des_ grads.
        /// </summary>
        /// <param name="grad">
        /// The p 0.
        /// </param>
        [Given(@"ich trage das Armband des (.*)\. Grads")]
        public void GivenIchTrageDasArmbandDesGrads(int grad)
        {
            this.GivenIchInteressiereMichFurCleanCodeDevelopment();
            this.WhenIchDemCleanCodeRegisterBeitrete();
            this.ThenLegeIchDasArmbandDesGradsAnEinenArmAn(grad);
        }

        /// <summary>
        /// The given ich trage das armband des_ grads seit tagen am gleichen arm.
        /// </summary>
        /// <param name="grad">
        /// The p 0.
        /// </param>
        /// <param name="anzahlTage">
        /// The p 1.
        /// </param>
        [Given(@"Ich trage das Armband des (.*)\. Grads seit (.*) Tagen am gleichen Arm")]
        public void GivenIchTrageDasArmbandDes_GradsSeitTagenAmGleichenArm(int grad, int anzahlTage)
        {
            this.Stichtag = this.Stichtag.AddDays(-anzahlTage);
            this.GivenIchTrageDasArmbandDesGrads(grad);
        }

        /// <summary>
        /// The stichtag festlegen.
        /// </summary>
        [BeforeScenario]
        public void StichtagFestlegen()
        {
            this.Stichtag = new DateTime(2013, 3, 24);
        }

        /// <summary>
        /// The then darf ich das armband am selben arm weitertragen.
        /// </summary>
        [Then(@"darf ich das Armband am selben Arm weitertragen")]
        public void ThenDarfIchDasArmbandAmSelbenArmWeitertragen()
        {
            Assert.That(this.me.TageSeitArmbandwechsel(this.Stichtag), Is.EqualTo(1));
        }

        /// <summary>
        /// The then lege ich das armband des_ grads an einen arm an.
        /// </summary>
        /// <param name="grad">
        /// The p 0.
        /// </param>
        [Then(@"lege ich das Armband des (.*)\. Grads an einen Arm an")]
        public void ThenLegeIchDasArmbandDesGradsAnEinenArmAn(int grad)
        {
            var armband = new Armband(grad);
            this.me.Anlegen(armband, this.Stichtag);

            Assert.That(this.me.Armband, Is.EqualTo(armband));
        }

        /// <summary>
        /// The then muss ich mein armband zum anderen arm wechseln.
        /// </summary>
        [Then(@"muss ich mein Armband zum anderen Arm wechseln")]
        public void ThenMussIchMeinArmbandZumAnderenArmWechseln()
        {
            Assert.That(this.me.TageSeitArmbandwechsel(this.Stichtag), Is.EqualTo(1));
        }

        /// <summary>
        /// The then tausche ich mein armband gegen das des_ grads.
        /// </summary>
        /// <param name="grad">
        /// The p 0.
        /// </param>
        [Then(@"tausche ich mein Armband gegen das des (.*)\. Grads")]
        public void ThenTauscheIchMeinArmbandGegenDasDesGrads(int grad)
        {
            Assert.That(this.me.Armband.Grad, Is.EqualTo(grad));
        }

        /// <summary>
        /// The when ich alle praktiken und prinzipien des grads eingehalten habe.
        /// </summary>
        [When(@"ich alle Praktiken und Prinzipien des Grads eingehalten habe")]
        public void WhenIchAllePraktikenUndPrinzipienDesGradsEingehaltenHabe()
        {
            foreach (Baustein prinzip in this.reflektion.Prinzipien)
            {
                this.reflektion.RechenschaftAblegen(prinzip, true);
            }

            this.me.Reflektieren(this.reflektion, this.Stichtag);
        }

        /// <summary>
        /// The when ich am ende des tages meine arbeit nicht reflektiere.
        /// </summary>
        [When(@"ich am Ende des Tages meine Arbeit nicht reflektiere")]
        public void WhenIchAmEndeDesTagesMeineArbeitNichtReflektiere()
        {
            this.Stichtag = this.Stichtag.Date.AddDays(2);
        }

        /// <summary>
        /// The when ich am ende des tages meine arbeit reflektiere.
        /// </summary>
        [When(@"ich am Ende des Tages meine Arbeit reflektiere")]
        public void WhenIchAmEndeDesTagesMeineArbeitReflektiere()
        {
            this.Stichtag = new DateTime(2013, 3, 25);
            this.reflektion = new Reflektion(this.me.Armband);
        }

        /// <summary>
        /// The when ich dem clean code register beitrete.
        /// </summary>
        [When(@"Ich dem Clean Code Register beitrete")]
        public void WhenIchDemCleanCodeRegisterBeitrete()
        {
            this.register = new Register();
            this.me.Beitreten(this.register);
        }

        /// <summary>
        /// The when ich meine clean code karriere beginne.
        /// </summary>
        [When(@"Ich meine Clean Code Karriere beginne")]
        public void WhenIchMeineCleanCodeKarriereBeginne()
        {
            this.me.KarriereBeginnen(this.Stichtag);
        }

        /// <summary>
        /// The when ich nicht alle praktiken und prinzipien des grads eingehalten habe.
        /// </summary>
        [When(@"ich nicht alle Praktiken und Prinzipien des Grads eingehalten habe")]
        public void WhenIchNichtAllePraktikenUndPrinzipienDesGradsEingehaltenHabe()
        {
            this.reflektion.RechenschaftAblegen(this.reflektion.Prinzipien.First(), true);
            this.me.Reflektieren(this.reflektion, this.Stichtag);
        }
    }
}